package crypt

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/base64"
	"errors"
	"io"
)

/*
 From：   https://github.com/ouqiang/goutil
 Author：
 Date：   2023/09/27 12:30
*/

// AesCFBEncrypt Aes加密
func AesCFBEncrypt(msg, key string) (string, error) {
	msgByte := []byte(msg)
	keyByte := []byte(key)
	block, err := aes.NewCipher(keyByte)
	if err != nil {
		return "", err
	}
	cipherText := make([]byte, aes.BlockSize+len(msgByte))
	iv := cipherText[:aes.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return "", err
	}

	stream := cipher.NewCFBEncrypter(block, iv)
	stream.XORKeyStream(cipherText[aes.BlockSize:], msgByte)

	// base64 编码
	base64str := base64.StdEncoding.EncodeToString(cipherText)
	return base64str, nil
}

// AesCFBDecrypt Aes解密
func AesCFBDecrypt(base64str, key string) (string, error) {
	keyByte := []byte(key)
	// base64 解密
	cipherText, _ := base64.StdEncoding.DecodeString(base64str)
	block, err := aes.NewCipher(keyByte)
	if err != nil {
		return "", err
	}
	if len(cipherText) < aes.BlockSize {
		return "", errors.New("cipherText too short")
	}
	iv := cipherText[:aes.BlockSize]
	cipherText = cipherText[aes.BlockSize:]

	stream := cipher.NewCFBDecrypter(block, iv)
	stream.XORKeyStream(cipherText, cipherText)

	return string(cipherText), nil
}
